package org.changs.nav.delegate.amap;

import android.content.Context;

import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.model.AMapCarInfo;
import com.amap.api.navi.model.AMapNaviPath;
import com.amap.api.navi.model.NaviLatLng;

import org.changs.nav.delegate.MapSwitchDelegate;
import org.changs.nav.delegate.amap.domain.PoiPoint;
import org.changs.nav.delegate.amap.domain.SimpleLocation;
import org.changs.nav.delegate.global.AmapLocationTask;
import org.changs.nav.delegate.global.AmapNavHelper;
import org.changs.nav.ui.nav.BaseMapFragment;
import org.changs.nav.ui.nav.RouteListFragment;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import javax.inject.Inject;

import aplug.data.prefs.PreferencesHelper;

/**
 * Created by yincs on 2017/10/14.
 */

public class AmapRouteHelper {

    private final AmapNavHelper mAmapNavHelper;
    private final PreferencesHelper mPreferencesHelper;
    private final AmapLocationTask mAmapLocationTask;
    private final MapSwitchDelegate mMapSwitchDelegate;

    private MySimpleAMapNaviListener mAMapNaviListener;
    private AMapNavi mAMapNavi;

    @Inject
    public AmapRouteHelper(AmapNavHelper amapNavHelper, PreferencesHelper preferencesHelper, AmapLocationTask amapLocationTask, MapSwitchDelegate mapSwitchDelegate) {
        mAmapNavHelper = amapNavHelper;
        mPreferencesHelper = preferencesHelper;
        mAmapLocationTask = amapLocationTask;

        mAMapNavi = amapNavHelper.getAMapNavi();
        mMapSwitchDelegate = mapSwitchDelegate;
    }

    public void calculate(NaviLatLng end, List<NaviLatLng> ways, AMapNaviListener listener) {
        SimpleLocation location = mAmapLocationTask.getLocation();
        if (location == null) {
            listener.onError(-1, "定位失败");
            return;
        }
        calculate(new NaviLatLng(location.getLatitude(), location.getLongitude()), end, ways, listener);
    }

    public void calculate(NaviLatLng str, NaviLatLng end, List<NaviLatLng> ways, AMapNaviListener listener) {
        int strategyFlag = 0;
        boolean congestion = mPreferencesHelper.isCongestion();
        boolean avoidCost = mPreferencesHelper.isAvoidCost();
        boolean avoidSpeed = mPreferencesHelper.isAvoidSpeed();
        boolean highSpeed = mPreferencesHelper.isHighSpeed();
        String carNumber = mPreferencesHelper.getCarNumber();
        boolean restriction = mPreferencesHelper.isRestriction();
        boolean vehicleLoadSwitch = mPreferencesHelper.isVehicleLoadSwitch();
        String vehicleLoad = mPreferencesHelper.getVehicleLoad();

        AMapCarInfo carInfo = new AMapCarInfo();
        carInfo.setCarNumber(carNumber);
        carInfo.setRestriction(restriction);
        carInfo.setVehicleLoad(vehicleLoad);
        carInfo.setCarType("1");
        carInfo.setVehicleLoadSwitch(vehicleLoadSwitch);
        mAMapNavi.setCarInfo(carInfo);
        try {
            strategyFlag = mAMapNavi.strategyConvert(congestion, avoidSpeed, avoidCost, highSpeed, true);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (mAMapNaviListener != null) mAMapNavi.removeAMapNaviListener(mAMapNaviListener);
        mAMapNaviListener = new MySimpleAMapNaviListener(listener);
        mAMapNavi.addAMapNaviListener(mAMapNaviListener);
        mAMapNavi.calculateDriveRoute(Collections.singletonList(str),
                Collections.singletonList(end), ways, strategyFlag);
    }

    public void cancel() {
        if (mAMapNaviListener != null) {
            mAMapNavi.removeAMapNaviListener(mAMapNaviListener);
            mAMapNaviListener = null;
        }
    }

    public void calculate(BaseMapFragment host, String name, String address, double lat, double lon) {
        host.showLoading().setMessage("路线规划中...")
                .cancelAction(this::cancel);

        calculate(new NaviLatLng(lat, lon),
                new ArrayList<>(), new AmapRouteHelper.AMapNaviListener() {
                    @Override
                    public void onError(int code, String msg) {
                        if (host.isDetached()) return;
                        host.onError("路线规划失败 " + code);
                        host.hideLoading();
                    }

                    @Override
                    public void onSuccess(int[] ints) {
                        PoiPoint endPoint = new PoiPoint(name, address, lat, lon);
                        mMapSwitchDelegate.switch2RouteList(ints, endPoint);
                        host.startFragment(host, RouteListFragment.newInstance(ints));
                    }
                });
    }

    private class MySimpleAMapNaviListener extends SimpleAMapNaviListener {
        private AMapNaviListener aMapNaviListener;

        public MySimpleAMapNaviListener(AMapNaviListener aMapNaviListener) {
            this.aMapNaviListener = aMapNaviListener;
        }

        @Override
        public void onInitNaviSuccess() {
        }

        @Override
        public void onCalculateRouteFailure(int i) {
            mAMapNavi.removeAMapNaviListener(this);
            aMapNaviListener.onError(i, "离线计算失败");
        }

        @Override
        public void onCalculateRouteSuccess(int[] ints) {
            mAMapNavi.removeAMapNaviListener(this);
            if (ints.length == 0) {
                aMapNaviListener.onError(-1, "没有线路");
                return;
            }
            aMapNaviListener.onSuccess(ints);
        }
    }

    public static ArrayList<AMapNaviPath> getAMapNaviPaths(Context context, int[] ints) {
        AMapNavi aMapNavi = AMapNavi.getInstance(context.getApplicationContext());
        HashMap<Integer, AMapNaviPath> paths = aMapNavi.getNaviPaths();
        if (paths == null || paths.size() == 0) return null;
        ArrayList<AMapNaviPath> arrayList = new ArrayList<>(ints.length);
        for (int anInt : ints) {
            arrayList.add(paths.get(anInt));
        }
        return arrayList;
    }

    public static String getCostTime(int time) {
        if (time < 0) return "未知时间";
        time = time / 60;//分钟
        int hour = time / 60;
        int min = time % 60;
        if (hour == 0 && min == 0)
            min = 1;
        String result = "";
        if (hour != 0)
            result += hour + "时";
        result += min + "分钟";
        return result;
    }

    public static String getCostDistance(int distance) {
        if (distance < 0) return "未知距离";
        return distance + "米";
    }


    public interface AMapNaviListener {

        void onError(int code, String msg);

        void onSuccess(int[] ints);
    }


}
